package com.xneure.code.plantask;

public abstract class PlanTask{
	private boolean isRun = false;
	private long interval = 1000;
	protected long currRunCount = 0;
	private TimerEvent event;
	private boolean promptlyRun = false;
	private Thread timeThread;
	private TimingCheck tc = new TimingCheck();
	private boolean destroy = false;

	class TimingCheck{
	}

	// 创建定时器
	private Thread getTask(){
		Thread thread = new Thread(){
			@Override
			public void run(){
				while(parentIsAlive()){
					if(isStop() == false){
						timeTask();
					}
				}
			}
		};
		thread.setDaemon(true);
		return thread;
	}

	private void timeTask(){
		try{
			synchronized(tc){
				tc.wait(interval);
			}
			if(isIgnore() == false){
				if(isRun == false){
					isRun = true;
				}
				currRunCount++;
				event.tick();
			}
		}catch(Exception e){
		}
	}

	private boolean parentIsAlive(){
		return destroy || timeThread.isInterrupted();
	}

	/**
	 * 是否跳过
	 */
	protected boolean isIgnore(){
		return false;
	}

	/**
	 * 是否停止
	 */
	protected abstract boolean isStop();

	/**
	 * 是否允许执行
	 */
	protected abstract boolean checkParam();

	/**
	 * 执行结束
	 */
	protected void end(){
		synchronized(tc){
			destroy = true;
			tc.notify();
		}
	}

	/**
	 * 执行计划任务
	 */
	public boolean start(){
		if(checkParam()){
			if(destroy){
				throw new RuntimeException("定时器已经销毁。");
			}
			synchronized(tc){
				if(timeThread == null){
					timeThread = getTask();
					timeThread.start();
				}
			}
			isRun = true;
			event.tick();
		}
		return isRun;
	}

	/**
	 * 停止计划任务
	 */
	public void stop(){
		isRun = false;
		timeThread = null;
	}

	/**
	 * 是否已经执行计划任务 如果设置了开始时间，在开始时间之后才能返回 true
	 * 
	 * @return boolean
	 */
	public boolean isRun(){
		return isRun;
	}

	/**
	 * 是否立即执行
	 * 
	 * @return boolean
	 */
	public boolean isPromptlyRun(){
		return promptlyRun;
	}

	/**
	 * 设置是否立即执行 默认为false
	 * 
	 * @param promptlyRun void
	 */
	public void setPromptlyRun(boolean promptlyRun){
		this.promptlyRun = promptlyRun;
	}

	/**
	 * 计划任务的时间
	 * 
	 * @param call void
	 */
	public void setRunEvent(TimerEvent event){
		this.event = event;
	}

	/**
	 * 执行间隔
	 * 
	 * @return long
	 */
	public long getInterval(){
		return interval;
	}

	/**
	 * 设置执行间隔
	 * 
	 * @param interval void
	 */
	public void setInterval(long interval){
		this.interval = interval;
	}

	/**
	 * 获取要执行的次数
	 * 
	 * @return long
	 */
	public long getCurrRunCount(){
		return currRunCount;
	}
}
